from django.conf import settings
from django.contrib.auth.models import Permission, User
from django.contrib.contenttypes.models import ContentType
from django.core import urlresolvers
from django.http import HttpResponseRedirect
from django.utils.decorators import available_attrs
from fb.auth.models import FacebookProfile
from fb.utils import fql

try:
    from functools import wraps
except ImportError:
    from django.utils.functional import wraps  # Python 2.4 fallback.

import sys
import urllib

def fb_permission_required(*args):
  perms_needed = args
  
  def decorator(view_func):
    @wraps(view_func, assigned=available_attrs(view_func))
    def _wrapped_view(request, *args, **kwargs):
      perms_to_get = []
      user = request.user
      for perm in perms_needed:
        if not user.has_perm('auth.%s' % perm):
          perms_to_get.append(perm)
      
      # If we have all required permissions, continue with the view as normal
      if not perms_to_get:
        return view_func(request, *args, **kwargs)
      
      # Otherwise push the user into the Facebook permission request dialog
      redirect_uri = request.build_absolute_uri(
        urlresolvers.reverse('perm_request_handler')
      )
      dialog_path = 'https://www.facebook.com/dialog/oauth/'
      dialog_params = {
        'client_id': settings.FACEBOOK_APP_ID,
        'response_type': 'token',
        'scope': ','.join(perms_to_get),
        'redirect_uri': redirect_uri,
        'state': request.user.username,
        'display': 'page'
      }
      dialog_uri = '%s?%s' % (dialog_path, urllib.urlencode(dialog_params))
      return HttpResponseRedirect(dialog_uri)
      
    return _wrapped_view
  return decorator


def remove_permissions_from_users(to_remove):
  ct = ContentType.objects.get_for_model(FacebookProfile)
  fb_perms = Permission.objects.filter(content_type=ct)
  fb_perm_lookup = dict([[x.codename, x] for x in fb_perms])
  
  users = User.objects.filter(username__in = to_remove.keys())
  for user in users:
    for perm in to_remove[user.username]:
      user.user_permissions.remove(fb_perm_lookup[perm])
      
  
def sync_permission_options():
  sys.stdout.write('Fetching permissions from Facebook...')
  query = "SELECT permission_name, header FROM permissions_info WHERE permission_name"
  perms = fql.query(query)
  sys.stdout.write('done!\n')

  ct = ContentType.objects.get_for_model(FacebookProfile)
  
  sys.stdout.write('Fetching existing permissions from database...')
  existing_perms = Permission.objects.filter(content_type=ct)
  existing_lookup = dict(
    [[x.codename, x] for x in existing_perms]
  )
  sys.stdout.write('done!\n')
  
  for perm in perms:
    code = perm['permission_name']
    if not existing_lookup.has_key(code):
      p = Permission(codename=code, name=perm['header'], content_type=ct)
      sys.stdout.write('Adding perm: %s, %s\n' % (p.codename, p.name))
      p.save()
    else:
      p_ex = existing_lookup[code]
      if p_ex.name != perm['header']:
        p_ex.name= perm['header']
        sys.stdout.write(
          'Updating perm: %s with new name %s\n' % (p_ex.codename, p_ex.name)
        )
        p_ex.save()